package se480.paf.filters.impl;



import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.log4j.Logger;

import se480.paf.filters.ActiveFilter;
import se480.paf.pipes.Item;
import se480.paf.pipes.Pipe;

/**
 * This filter performs several cleaning tasks on each word:
 * 1) removes all stop words 
 * 2) removes non-alpha from all words
 * 3) saves word as lower case
 * 
 * @author mmichalak
 *
 */
public class CleanWordsFilter implements ActiveFilter {
	
	static Logger logger = Logger.getLogger("CleanWordsFilter");
	
	String name = "CleanWordsFilter";
	int msSleep = 2000; // Default Thread sleep time
	
	public Pipe<Item> inPipe;
	public Pipe<Item> outPipe;

	static HashMap<String, String> stopWords = null;
	static String regExFilter = "[^a-zA-Z0-9]";
	static Pattern pattern = null;

	
	@Override
	public void run() {
		
		loadStopWords();
		
		// Create RegEx Pattern
		CleanWordsFilter.pattern = Pattern.compile(regExFilter);
		
		try {
		      int i = 0;
		      while (true) {
		    	 if (!inPipe.isEmpty()) {
		    		 Item item = inPipe.removeItem();
		    		 process(item);
		    	 }
		    	  
		    	 logger.debug(name + " wake: " + i++);
		         Thread.sleep(msSleep);

		      }
      } catch (InterruptedException e) {
    	  //logger.debug(name + " interrupted.");
      }
      logger.debug(name + " exiting.");

	}

	@Override
	/**
	 * Filter task processing
	 * Remove the stop words and "Clean" the words
	 * Cleaning involved removing non-alpha chars and empty words
	 */
	public void process(Item item) {
		long startTime = System.currentTimeMillis();
		 ArrayList<String> words = (ArrayList<String>)item.getItem();
		 logger.debug(name + " picked up " + item.getName());
		 
			ArrayList<String> wordsWOutStops = new ArrayList<String>();
			
			int totalWords = 0;
			for (String word : words) {
				totalWords += 1;
				// Only keep non-Stop Words and non-blanks
				if (stopWords.get(word) == null) {
					//String cleanWord = word.replaceAll(CleanWordsFilter.regExFilter, "");
					Matcher matcher2 = CleanWordsFilter.pattern.matcher(word);
				    String cleanWord = matcher2.replaceAll("");
					logger.debug("RegEx: " + word + "   " + cleanWord); // prints: true
					 if (!cleanWord.trim().equals(""))
						 wordsWOutStops.add( cleanWord.toLowerCase() );
				}
			}

	    item.setItem(wordsWOutStops);
	    long endTime = System.currentTimeMillis();
	    item.addExecuteTimes(name + " - " + (endTime - startTime));
	    logger.debug(wordsWOutStops);
	    
	    outPipe.addItem(item);
	}

	/**
	 *  Load stop word file into map
	 */
	private void loadStopWords() {
		try {
	        String sCurrentLine;
	 
	        String fileName = "c:\\SE480\\DataFiles\\stopwords.txt";
	        /*FileReader r = new FileReader(
					FileReadTest.class.getClassLoader().getResource(fileName).getPath()
			        .replaceAll("%20", " "));*/
	        FileReader r = new FileReader(fileName);
	        BufferedReader br = new BufferedReader(r);
	        
	        int N = 0;
	        HashMap<String, String> stopWords = new HashMap<String, String>();
	        while ((sCurrentLine = br.readLine()) != null) {
	        	if (sCurrentLine != null || !sCurrentLine.isEmpty())
	        		stopWords.put(sCurrentLine.trim(), sCurrentLine.trim());
	        	N++;
		       //logger.debug(sCurrentLine);
	        } 

	        logger.debug("Number of stop word lines read:  " + N);
	        
	        CleanWordsFilter.stopWords = stopWords;
	        
		} catch (FileNotFoundException e) {
	        e.printStackTrace();
	    } catch (IOException e) {
	        e.printStackTrace();
	    }
	
	}

	@Override
	public void setInPipe(Pipe<Item> pipe) {
		this.inPipe = pipe;
	}

	@Override
	public void setOutPipe(Pipe<Item> pipe) {
		this.outPipe = pipe;
	}


	@Override
	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String getName() {
		return this.name;
	}

	@Override
	public void setSleep(int msSleep) {
		this.msSleep = msSleep;
	}

	@Override
	public int getSleep() {
		return this.msSleep;
	}

	@Override
	public Pipe<Item> getInPipe() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Pipe<Item> getOutPipe() {
		// TODO Auto-generated method stub
		return null;
	}

}
